package com.dw.message.socket;

import com.dw.message.config.WebSocketServerConfig;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@Component
@ServerEndpoint(value = "/lei/socket",configurator = WebSocketServerConfig.class)
@CrossOrigin(origins = "*")
public class LeiSocket {

    @Resource
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 记录当前在线连接数
     */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /**
     * 用来存放所有的在线客户端
     */
    private static Map<String,LeiSocket> clients = new ConcurrentHashMap<>();

    /**
     * 某个客户端连接session会话
     */
    private Session session;

    /**
     * 标识当前会话的key
     */
    private String erp = "";

    private List<String> idList = new ArrayList<>();

    @OnOpen
    @SneakyThrows
    public void onOpen(Session session, EndpointConfig endpointConfig){
        Map<String, Object> userProperties = endpointConfig.getUserProperties();
        String erp = (String) userProperties.get("erp");
        this.erp = erp;
        this.session = session;
        if(clients.containsKey(this.erp)){
            clients.get(this.erp).session.close();
            clients.remove(this.erp);
            onlineCount.decrementAndGet();
        }
        clients.put(this.erp,this);
        onlineCount.incrementAndGet();
        log.info("有新连接加入：{},当前在线人数:{}",erp,onlineCount.get());
        idList.add(erp);
    }

    @OnMessage
    public void onMessage(String message,Session session){
        log.info("来自客户端{}的消息：{}",this.erp,message);
        if(StringUtils.equals(message,"ྀི")){
            idList.forEach(id->{
                sendMessage(id);
            });
        } else {
            this.sendMessage(message);
        }
    }

    @OnClose
    @SneakyThrows
    public void onClose(){
        if(clients.containsKey(erp)){
            clients.get(erp).session.close();
            clients.remove(erp);
            onlineCount.decrementAndGet();
        }
        log.info("有连接断开{}，当前在线人数为：{}",this.erp,onlineCount.get());
    }

    @OnError
    @SneakyThrows
    public void onError(Session session, Throwable throwable){
        log.error("socket发生错误：{}",throwable.getMessage());
        session.close();
    }

    @SneakyThrows
    public void sendMessage(String message,Session session){
        log.info("服务端给客户端{}发送消息{}",this.erp,message);
        session.getBasicRemote().sendText(message);
    }

    @SneakyThrows
    public void sendMessage(String message){
        for (Map.Entry<String, LeiSocket> sessionEntry: clients.entrySet()){
            String erp = sessionEntry.getKey();
            LeiSocket leiSocket = sessionEntry.getValue();
            Session session = leiSocket.session;
            session.getBasicRemote().sendText(message);
        }
    }
}
